package com.restaurant.application.shoplist;

import com.google.common.base.Strings;
import com.nebutown.base.ViewSpec;
import com.nebutown.base.data.View;
import com.nebutown.base.data.ViewUpdate;
import com.nebutown.commonunits.dataface.DataModes;
import com.nebutown.commonunits.dataface.EntryTypes;
import com.nebutown.commonunits.dataface.FormShell;
import com.nebutown.commonunits.dataface.TableShell;
import com.nebutown.commonunits.dataface.definitions.*;
import com.nebutown.commonunits.uidataface.UIDataFace;
import com.nebutown.generation.basicdata.UIDRecord;
import com.nebutown.generation.basictype.StringData;
import com.nebutown.generation.basictype.UID;
import com.restaurant.application.minifacade.data.ShopBO;
import com.restaurant.application.shop.Shop;
import com.restaurant.application.shop.support.ShopData;
import com.restaurant.application.shop.support.ShopVo;
import com.restaurant.application.shoplist.support.AbstractShopList;
import com.restaurant.application.shoplist.support.ShopListPageVo;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class ShopListImpl extends AbstractShopList {
    @Override
    public ViewUpdate insert(int[] seq) {
        Shop shop = createNode(Shop.class);
        return returnPushInContainer(shop.getId(), false);
    }

    @Override
    public ViewUpdate search(ShopListPageVo search, int[] seq) {
        return returnView(newCommonTable(search, 1));
    }

    @Override
    public ViewUpdate detail(int[] seq) {
        return null;
    }

    @Override
    public ViewUpdate edit(int[] seq) {
        return null;
    }

    @Override
    public ViewUpdate delete(int[] seq) {
        getData().getShops().remove(seq[0]);
        return returnView(newCommonTable(new ShopListPageVo(), 1));
    }

    @Override
    public ViewUpdate switchPage(StringData switchPage, int[] seq) {
        return null;
    }

    @Override
    public List<UID> findAllShop() {
        return getData().duplicate().getShops().getAll().stream().map(UIDRecord::getUid).collect(Collectors.toList());
    }

    @Override
    public List<ShopVo> findAllShopData() {
        return getData().duplicate().getShops().getAll().stream().map(UIDRecord::getUid)
                .map(e -> {
                    ShopVo vo = new ShopVo();
                    ShopData shopData = getUnit(Shop.class, e).findData();
                    return vo.withId(shopData.getId()).withName(shopData.getName());
                }).collect(Collectors.toList());
    }

    @Override
    public void addShop(UID shopId) {
        if (shopId != null) {
            getData().getShops().add(shopId);
        }
    }

    @Override
    public UID findShopByName(String shopName) {
        return getData().duplicate().getShops().getAll().stream().map(UIDRecord::getUid)
                .filter(e -> {
                    ShopData shopData = getUnit(Shop.class, e).findData();
                    return shopData.getName().equals(shopName);
                }).findAny().orElse(null);
    }

    @Override
    public List<ShopBO> findAllShopBO() {
        return getData().duplicate().getShops().getAll().stream().map(UIDRecord::getUid)
                .map(e -> {
                    ShopBO vo = new ShopBO();
                    ShopData shopData = getUnit(Shop.class, e).findData();
                    AddressEntry address = shopData.getAddress();
                    String ad = "";
                    if (address != null) {
                        List<String> scoped = address.getScoped();
                        String s = scoped.stream().distinct().collect(Collectors.joining());
                        ad = s + (shopData.getAddressDetail() == null ? "" : shopData.getAddressDetail());
                    }
                    return vo.withShopId(shopData.getId()).withShopName(shopData.getName()).withAddress(ad)
                            .withImgUrl(shopData.getImgUrl() != null && shopData.getImgUrl().size() > 0 ? shopData.getImgUrl().get(0) : "").withPhone(shopData.getPhone());
                }).collect(Collectors.toList());
    }

    @Override
    public int checkMaxId() {
        return getData().duplicate().getShops().getAll().stream().map(UIDRecord::getUid)
                .map(e -> Integer.parseInt(getUnit(Shop.class, e).findData().getId())
                ).max(Integer::compareTo).orElse(0);
    }

    @Override
    public View getFullView() {
        return newCommonTable(new ShopListPageVo(), 1);
    }

    @Override
    public View getViewLead(ViewSpec viewSpec) {
        return null;
    }

    private View newCommonTable(ShopListPageVo search, int pageNum) {
        int pageSize = 10;
        List<UIDRecord> records = getData().getShops().getAll();
        int totalRecord = records.size();
        int totalPage = (totalRecord + pageSize + 1) / pageSize;
        List<UIDRecord> recordList = records.stream()
                .filter(e -> {
                    if (!Strings.isNullOrEmpty(search.getName())) {
                        return getUnit(Shop.class, e.getUid()).findData().getName().contains(search.getName());
                    }
                    return true;
                }).sorted(Comparator.comparing(x -> getUnit(Shop.class, x.getUid()).findData().getModifyTime()))
                .skip(pageSize * (pageNum - 1))
                .limit(pageSize).collect(Collectors.toList());
        PageInfo pageInfo = new PageInfo()
                .withPageNum(pageNum)
                .withPageSize(pageSize)
                .withTotalPage(totalPage)
                .withTotalRecord(totalRecord)
                .withJumpPath(getPath(CMD_SWITCHPAGE));
        PageForm pageForm = newFormShell(recordList, pageInfo).getForm();
        return getSingleton(UIDataFace.class).newGenericForm(unitPosition(), pageForm);
    }

    private FormShell newFormShell(List<UIDRecord> recordList, PageInfo pageInfo) {

        FormShell formShell = new FormShell("店铺列表", 4, 3);

        formShell.source(new ShopListPageVo(), DataModes.EDIT);

        formShell.at(0, 0, "")
                .getEntry("name", "")
                .placeHolder("店名")
                .simpleEntry(EntryTypes.STRING)
                .getContent().setEditable(true);

        formShell.at(0, 1, "搜索")
                .buttonField(getPath(CMD_SEARCH), "", true);
        formShell.at(0, 2, "新增")
                .buttonField(getPath(CMD_INSERT), "", false);

        List<ShopListPageVo> collect = recordList.stream().map(e -> {
            ShopData shopData = getUnit(Shop.class, e.getUid()).findData();
            String address = "";
            if (shopData.getAddress() != null) {
                address = String.join("", shopData.getAddress().getScoped());
            }
            if (shopData.getAddressDetail() != null) {
                address += shopData.getAddressDetail();
            }
            return new ShopListPageVo().withId(shopData.getId()).withName(shopData.getName()).withPhone(shopData.getPhone())
                    .withMail(shopData.getMail()).withAddress(address)
                    .withSeq(Long.valueOf(e.getSeq()));
        }).collect(Collectors.toList());
        TableShell<ShopListPageVo> tableShell = new TableShell<>(ShopListPageVo.class, collect).withPageInfo(pageInfo);

        tableShell.createColumn("id").withName("门店编号").cellCalculator(b -> {
            ShopListPageVo bean = (ShopListPageVo) b;
            return new CellData()
                    .withField(new FieldContent().withSimpleField(bean.getId()));
        });
        tableShell.createColumn("name").withName("门店").cellCalculator(b -> {
            ShopListPageVo bean = (ShopListPageVo) b;
            return new CellData()
                    .withField(new FieldContent().withSimpleField(bean.getName()));
        });
        tableShell.createColumn("phone").withName("电话").cellCalculator(b -> {
            ShopListPageVo bean = (ShopListPageVo) b;
            return new CellData()
                    .withField(new FieldContent().withSimpleField(bean.getPhone() == null ? "" : bean.getPhone()));
        });
        tableShell.createColumn("mail").withName("邮箱").cellCalculator(b -> {
            ShopListPageVo bean = (ShopListPageVo) b;
            return new CellData()
                    .withField(new FieldContent().withSimpleField(bean.getMail()));
        });
        tableShell.createColumn("address").withName("地址").cellCalculator(b -> {
            ShopListPageVo bean = (ShopListPageVo) b;
            return new CellData()
                    .withField(new FieldContent().withSimpleField(bean.getAddress()));
        });
        tableShell.createColumn("doSomething").withName("操作").cellCalculator(b -> {
            ShopListPageVo bean = (ShopListPageVo) b;
            return new CellData()
                    .withField(new FieldContent().withButton(new ButtonField().withLabel("查看").withButtonPath(getPath(CMD_DETAIL, bean.getSeq()))))
                    .withField(new FieldContent().withButton(new ButtonField().withLabel("编辑").withButtonPath(getPath(CMD_EDIT, bean.getSeq()))))
                    .withField(new FieldContent().withButton(new ButtonField().withLabel("删除").withButtonPath(getPath(CMD_DELETE, bean.getSeq()))));
        });

        formShell.at(3, 6, "店铺列表")
                .large(4, 1)
                .getEntry("error", "")
                .tableEntry(tableShell);

        return formShell;
    }
}
